﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace WorkLogSystem.Common
{
    public class ConvertTool
    {
        public static T DataRowToModel<T>(DataRow row) where T : new ()
        {
            if (row == null)
            {
                throw new Exception("在DataRowToModel时，DataRow为NULL");
            }
            T model = new T();
            Type modelType = typeof(T);

            // 获取所有公共属性
            PropertyInfo[] properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo property in properties)
            {
                // 检查属性是否可写
                if (!property.CanWrite)
                    continue;

                // 检查DataRow中是否包含与属性同名的列
                if (row.Table.Columns.Contains(property.Name))
                {
                    object value = row[property.Name];

                    // 处理DBNull情况
                    if (value == DBNull.Value)
                    {
                        // 如果属性是值类型且不可为null，则使用默认值
                        if (property.PropertyType.IsValueType && Nullable.GetUnderlyingType(property.PropertyType) == null)
                        {
                            value = Activator.CreateInstance(property.PropertyType);
                        }
                        else
                        {
                            value = null;
                        }
                    }

                    try
                    {
                        // 尝试转换类型并设置属性值
                        object convertedValue = ConvertValue(value, property.PropertyType);
                        property.SetValue(model, convertedValue, null);
                    }
                    catch
                    {
                        // 如果转换失败，可以记录日志或抛出异常
                        // 这里选择忽略，保持程序继续运行
                        continue;
                    }
                }
            }

            return model;
        }

        private static object ConvertValue(object value, Type targetType)
        {
            if (value == null)
                return null;

            // 如果目标类型是Nullable<T>，获取实际的T
            Type underlyingType = Nullable.GetUnderlyingType(targetType) ?? targetType;

            // 如果值已经是目标类型，直接返回
            if (underlyingType.IsInstanceOfType(value))
                return value;

            // 尝试转换类型
            try
            {
                return Convert.ChangeType(value, underlyingType);
            }
            catch
            {
                // 如果直接转换失败，尝试通过字符串解析
                try
                {
                    string stringValue = value.ToString();
                    return underlyingType.GetMethod("Parse", new[] { typeof(string) })?.Invoke(null, new object[] { stringValue });
                }
                catch
                {
                    // 所有尝试都失败，抛出异常或返回默认值
                    return underlyingType.IsValueType ? Activator.CreateInstance(underlyingType) : null;
                }
            }
        }

        public static Dictionary<string, object> DataRowToDictionary(DataRow row)
        {
            if (row == null)
            {
                throw new Exception("在DataRowToModel时，DataRow为NULL");
            }
            Dictionary<string, object> dic = new Dictionary<string, object>();
            foreach (DataColumn dataColumn in row.Table.Columns)
            {
                dic[dataColumn.ColumnName] = row[dataColumn.ColumnName] == DBNull.Value ? "": row[dataColumn.ColumnName];
            }
            return dic;
        }
    }
}
